import time
import pyautogui
import cv2
import logging
from pynput.mouse import Listener

from vo.ClicksVO import ClicksVO

# from vo import ClicksVO

clicks = {}
clicks_count = 0
interval = 2

# 创建一个logger
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)

# 创建一个handler用于写入日志文件
fh = logging.FileHandler('example.log')
fh.setLevel(logging.DEBUG)

# 再创建一个handler用于输出到控制台
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)

# 定义handler的输出格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setFormatter(formatter)
ch.setFormatter(formatter)

# 给logger添加handler
logger.addHandler(fh)
logger.addHandler(ch)


def testScreen():
    #福罐要点4次并看广告
    fgvo = ClicksVO('操作福罐', [{'img': './pic/fg_001.png', 'sleep': '1'},
                                 {'img': './pic/fg_002.png', 'sleep': '1'},
                                 {'img': './pic/fg_003.png', 'sleep': '32'},
                                 {'img': './pic/fg_004.png', 'sleep': '1'}])

    #热气球要点14下
    qqvo = ClicksVO('操作热气球', [{'img': './pic/qq_001.png', 'sleep': '1'},
                                 {'img': './pic/qq_001.png', 'sleep': '0.2'},
                                 {'img': './pic/qq_001.png', 'sleep': '0.2'},
                                 {'img': './pic/qq_001.png', 'sleep': '0.2'},
                                 {'img': './pic/qq_001.png', 'sleep': '0.2'},
                                 {'img': './pic/qq_001.png', 'sleep': '0.2'},
                                 {'img': './pic/qq_001.png', 'sleep': '0.2'},
                                 {'img': './pic/qq_001.png', 'sleep': '0.2'},
                                 {'img': './pic/qq_001.png', 'sleep': '0.2'},
                                 {'img': './pic/qq_001.png', 'sleep': '0.2'},
                                 {'img': './pic/qq_001.png', 'sleep': '0.2'},
                                 {'img': './pic/qq_001.png', 'sleep': '0.2'},
                                 {'img': './pic/qq_001.png', 'sleep': '0.2'},
                                 {'img': './pic/qq_001.png', 'sleep': '0.2'}])

    #升级菜品
    sjvo = ClicksVO('升级菜品', [{'img': './pic/sj_001.png', 'sleep': '1'},
                                 {'img': './pic/sj_002.png', 'sleep': '1', 'continue_time': 3},
                                 {'img': './pic/sj_003.png', 'sleep': '1'},
                                 {'img': './pic/sj_003.png', 'sleep': '1'}])

    #卖菜
    mcvo = ClicksVO('卖菜', [{'img': './pic/mc_001.png', 'sleep': '0.2','double': 8,'excu': 50},])

    # 升级建筑
    sjjzvo = ClicksVO('升级建筑', [{'img': './pic/sjjz_001.png', 'sleep': '1', 'continue_time': 5}])

    #领取金币要点4次并看广告
    jbvo = ClicksVO('领取金币', [{'img': './pic/jb_001.png', 'sleep': '1'},
                                 {'img': './pic/jb_002.png', 'sleep': '1'},
                                 {'img': './pic/jb_003.png', 'sleep': '32'},
                                 {'img': './pic/jb_004.png', 'sleep': '1'}])
    while True:
        execlicks(sjjzvo)
        execlicks(mcvo)
        execlicks(sjvo)
        execlicks(jbvo)
        execlicks(fgvo)
        execlicks(qqvo)
        logger.debug('已执行完一组动作，等待5秒')
        time.sleep(5)


def execlicks(myvo):
    try:
        #执行自动点击指令组
        logger.debug(myvo)
        logger.debug(myvo.name)
        # 获取 clicks 属性
        clicks = myvo.clicks
        # 遍历 clicks 列表
        for click in clicks:
            img = click['img']
            sleep = click['sleep']
            continue_time = click.get('continue_time', 0)
            double = click.get('double', 1)
            excu = click.get('excu', 0)
            logger.debug(f"Image: {img}, Sleep: {sleep}, continue_time: {continue_time}")
            routine(img, myvo.name + img + ',执行后等待:' + sleep, continue_time,double,excu)
            time.sleep(float(sleep))
    except Exception as e:
        logger.debug(f"发生异常,结束任务：{e}")
        # 进仅开发模式启用异常
        # raise ValueError(f"发生异常,结束任务：{e}")

def get_xy(img_model_path):
    """
    用来判定游戏画面的点击坐标
    :param img_model_path: 用来检测的图片路径
    :return: 以元组形式返回检测到的区域中心的坐标，如果没有找到匹配则返回 None
    """
    # 将图片截图并且保存
    pyautogui.screenshot().save("pic/screenshot.png")
    # 待读取图像
    img = cv2.imread("pic/screenshot.png")
    # 图像模板
    img_terminal = cv2.imread(img_model_path)

    if img is None or img_terminal is None:
        raise ValueError("Failed to load one of the images.")

    # 读取模板的高度宽度和通道数
    logger.debug(f'img_model_path:{img_model_path}')
    height, width, _ = img_terminal.shape

    # 使用 matchTemplate 进行模板匹配（标准平方差匹配）
    result = cv2.matchTemplate(img, img_terminal, cv2.TM_SQDIFF_NORMED)

    # 解析出匹配区域的左上角坐标
    min_val, _, min_loc, _ = cv2.minMaxLoc(result)

    # 设定阈值，如果最小值大于该阈值，则认为没有找到匹配
    threshold = 0.08  # 可以根据实际情况调整
    if min_val > threshold:
        logger.debug(f"No match found for {img_model_path}. Minimum value: {min_val}")
        raise ValueError("未匹配到有效的图案,结束任务;")
        # return None

    # 计算出匹配区域右下角坐标（左上角坐标加上模板的长宽即可得到）
    lower_right = (min_loc[0] + width, min_loc[1] + height)

    # 计算坐标的平均值并将其返回
    avg = (int((min_loc[0] + lower_right[0]) / 2), int((min_loc[1] + lower_right[1]) / 2))
    return avg

def auto_Click(var_avg, continue_time,double,excu):
    """
    输入一个元组，自动点击
    :param var_avg: 坐标元组
    :return: None
    """
    pyautogui.moveTo(var_avg[0]-excu, var_avg[1])
    # pyautogui.click(var_avg[0], var_avg[1], button='left')
    time.sleep(0.5)

    for i in range(double):
        pyautogui.mouseDown(button='left')
        # if continue_time is not None:
        time.sleep(continue_time)
        pyautogui.mouseUp(button='left')
        # pyautogui.click(duration=0.5)
        time.sleep(0.5)



def routine(img_model_path, name,continue_time,double,excu):
    avg = get_xy(img_model_path)
    logger.debug(f"正在点击{name},坐标是{avg},点击此处{double},x轴偏移量{excu}")
    auto_Click(avg,continue_time,double,excu)


def click_position():
    """
    在给定的位置 (x, y) 上进行左键点击，并以指定的时间间隔重复此操作。

    :param x: 屏幕上目标位置的X坐标
    :param y: 屏幕上目标位置的Y坐标
    :param interval: 两次点击之间的间隔时间（秒）
    """
    clisum = 0
    while True:
        logger.debug("记录的所有坐标:")
        for i in range(1, len(clicks) + 1):
            logger.debug(f"点击 {i}: {clicks[i]}")
            pyautogui.moveTo(x=clicks[i][0], y=clicks[i][1], duration=0.2)
            # pyautogui.click(duration=0.5)
            for _ in range(5):
                pyautogui.mouseDown(button='left')
                logger.debug("按下鼠标")
                time.sleep(0.2)
                pyautogui.mouseUp(button='left')
                logger.debug("松开鼠标")

        clisum += 1
        logger.debug(f'已执行{clisum}次指令,切换焦点至本程序，点击ctrl+C可停止运行')
        # 等待指定的时间间隔
        time.sleep(interval)


def getinput():
        print('欢迎来到 猫咪和汤 自动化程序\n您准备好了吗？\n')
        # print('')
        # print('2,编辑配置')
        # print('3,执行自动化脚本')
        user_input = input("输入[1],开始获取目标像素点\n 输入[2]启动图像识别模式\n ")
        return user_input


def on_click(x, y, button, pressed):
    global clicks_count, clicks  # 确保在函数内部可以访问这些全局变量
    if pressed:
        clicks_count += 1
        clicks[clicks_count] = [x,y]
        logger.debug(f"已记录坐标 ({clicks})")

    if clicks_count >= 2:
        return False  # 返回 False 会停止监听


if __name__ == "__main__":
    user_input = int(getinput())
    logger.debug(f'您的输入是{user_input}')
    if user_input == 1:
        logger.debug('请点击升级位置，然后点击出售第一道菜')
        with Listener(on_click=on_click) as listener:
            listener.join()
        interval = int(input("您希望每轮点击之间的间隔是多少秒?如果无特殊需求建议2秒~"))
        logger.debug('开始执行脚本')
        click_position()
    if user_input == 2:
        logger.debug('正在进入开发者模式~')
        testScreen()
    else:
        input("无效的输入,点击任意键任务结束~")